package com.godyao.service.impl;

import com.godyao.constant.LoginConstant;
import com.godyao.repository.*;
import com.godyao.model.RoleAuth;
import com.godyao.model.SecurityUser;
import com.godyao.model.User;
import com.godyao.model.UserRole;
import com.godyao.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author godyao
 * @date 2022/3/16
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private AuthRepository authRepository;

    @Autowired
    private RoleAuthRepository roleAuthRepository;

    @Lazy
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public SecurityUser loadByUsername(String username) {
        final User activeUser = userRepository.findByUsernameAndStatus(username, LoginConstant.USER_USED);
        if (Objects.nonNull(activeUser)) {
            final SecurityUser securityUser = new SecurityUser().setUsername(activeUser.getUsername()).setPassword(passwordEncoder.encode(activeUser.getPassword()));
            // 查询该用户的角色
            final List<UserRole> userRoles = userRoleRepository.findByUserIdAndStatus(activeUser.getUserId(), LoginConstant.USER_ROLE_USED);
            // 获取权限集合
            Collection<? extends GrantedAuthority> authorities = merge(userRoles);
            securityUser.setAuthorities(authorities);
            securityUser.setId(activeUser.getId());
            return securityUser;
        }
        return null;
    }

    private Collection<? extends GrantedAuthority> merge(List<UserRole> userRoles) {
        // 获取所有角色
        List<String> roles = listRoles(userRoles);
        // 获取所有权限
        List<String> auths = listAuths(userRoles);
        roles.addAll(auths);
        String[] a = {};
        return AuthorityUtils.createAuthorityList(roles.toArray(a));

    }

    private List<String> listAuths(List<UserRole> userRoles) {
        final List<String> authList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoles)) {
            userRoles.forEach(userRole -> {
                final List<RoleAuth> roleAuths = roleAuthRepository.findByRoleIdAndStatus(userRole.getRoleId(), LoginConstant.ROLE_AUTH_USED);
                // 查询权限
                if (!CollectionUtils.isEmpty(roleAuths)) {
                    roleAuths.forEach(roleAuth -> authRepository.findById(roleAuth.getAuthId()).ifPresent(authInfo -> authList.add(authInfo.getName())));
                }
            });
        }
        return authList;
    }

    private List<String> listRoles(List<UserRole> userRoles) {
        final List<String> roleList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoles)) {
            userRoles.forEach(userRole -> roleRepository.findById(userRole.getRoleId()).ifPresent(role -> roleList.add(role.getName())));
        }
        return roleList;
    }
}
